#ifndef LINKEDLIST_H
#define LINKEDLIST_H

template <typename T>
class LinkedList {
	struct node {
		node(T val) : value(val), next(0x0) {}
		~node() { delete next; }
		T value;
		node* next;
	};


	node* front;
	node** back;
  public:


	class Iterator {
		node **ref;
		node ***back;
	  public:
		Iterator(node** r, node*** b) : ref(r), back(b) {}
		T operator* () { return (*ref)->value; }
		void operator++() { ref = &((*ref)->next); }
		bool operator==(const Iterator &other) { return *(this->ref) == *(other.ref); }
		bool operator!=(const Iterator &other) { return !(*this == other); }

		void Remove() {
			if (!(*ref)) return;

			node* old = *ref;
			*ref = old->next;
			old->next = 0x0;
			delete old;

			if (!(*ref)) *back = ref;
		}
	};

	LinkedList() : front(0x0), back(&front) {}
	~LinkedList() { delete front; }

	void PushFront(T value) {
		node* n = new node(value);

		if (front) {
			n->next = front;
		} else {
			back = &(n->next);
		}

		front = n;
	}

	void PushBack(T value) {
		node* n = new node(value);

		*back = n;
		back = &(n->next);
	}

	Iterator Begin() { return Iterator(&front, &back); }
	Iterator End() { return Iterator(back, &back); }
};

#endif